package cn.kgc.springboot.controller;

import cn.kgc.springboot.dto.UserDTO;
import cn.kgc.springboot.dto.UserPageDTO;
import cn.kgc.springboot.entity.User;
import cn.kgc.springboot.service.UserService;
import cn.kgc.springboot.util.CodeMsg;
import cn.kgc.springboot.util.RedisUtil;
import cn.kgc.springboot.util.ResponseResult;
import cn.kgc.springboot.util.SaltUtil;
import cn.kgc.springboot.vo.UserVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author: hengge
 * @version: v1.0
 * @DATE: 2022/11/21
 */
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtil redisUtil;

    //1.分页查询 -->查询所有 搜索
    @RequestMapping("all")
    public ResponseResult selectUserPage(UserPageDTO userPageDTO) {
        ResponseResult responseResult = userService.selectPage(userPageDTO);
        return responseResult;
    }

    //2.更新state状态值
    @RequestMapping("updateState")
    public ResponseResult updateUserState(User user) {
        ResponseResult responseResult = userService.updateUserState(user);
        return responseResult;
    }

    //3.添加操作
    @RequestMapping("add")
    public ResponseResult addUser(@RequestBody UserVO userVO) {
        System.out.println("userVO username= " + userVO.getUsername());  //userVO username= hezhangheng
        System.out.println("userVO roles= " + userVO.getRoles());        //userVO roles= [普通用户, 管理员, 超级管理员]

        //添加用户信息
        ResponseResult responseResult = userService.addUser(userVO);
        return responseResult;
    }

    //4.回显数据 根据id，查询用户信息
    @RequestMapping("getById")
    public ResponseResult getUserById(Integer id) {
        ResponseResult responseResult = userService.getUserVOById(id);
        return responseResult;
    }

    //5.编辑操作
    @RequiresRoles({"root"})  //基于角色的控制
    @RequestMapping("update")
    public ResponseResult updateUser(@RequestBody UserVO userVO){
        ResponseResult responseResult = userService.updateUser(userVO);
        return responseResult;
    }

    //6.删除操作
    @RequiresPermissions({"user:delete"})  //基于权限字符串的权限控制
    @RequestMapping("delete")
    public ResponseResult deleteUser(String ids){
        ResponseResult responseResult =  userService.deleteUser(ids);
        return responseResult;
    }

    //菜单的动态加载
    //7.加载菜单的方法
    @RequestMapping("loadMenu")
    //使用Map<>集合返回数据
    public Map<String,Object> loadMenu(String username){
        System.out.println("username = " + username);
        Map<String,Object> map =  userService.loadMenu(username);
        return map;
    }

    //8.登录操作
    @RequestMapping("login")
    //@SessionAttribute("code"):从session中取出code验证码
    public ResponseResult login(UserDTO userDTO, @SessionAttribute("code") String code, HttpServletRequest request){

        //获取认证主体subject 登录认证
        Subject subject = SecurityUtils.getSubject();
        //创建令牌
        UsernamePasswordToken token = new UsernamePasswordToken(userDTO.getUsername(), userDTO.getPassword());

        //开启记住我的功能
        if("true".equals(userDTO.getRememberMe())){
            token.setRememberMe(true);
        }

        //返回一个包含分配给该 session 会话的唯一标识符的字符串。
        String id = request.getSession().getId();
        System.out.println("id = " + id);
        //获取指定key的值(此处返回验证码)
        String redisCode = redisUtil.getValue(id);

        System.out.println("code = " + code);
        System.out.println("redisCode = " + redisCode);

        ResponseResult responseResult = new ResponseResult();
        if(redisCode.equals(userDTO.getCaptcha())){
            //认证通过，登录subject的login的方法
            subject.login(token);
            responseResult.setMsg(CodeMsg.LOGIN_SUCCESS.getMsg());
            responseResult.setCode(CodeMsg.LOGIN_SUCCESS.getCode());

        }else{
            //添加全局异常，若是出现NullPointerException异常，则表示redis中的验证码已失效
            try {
                responseResult.setMsg(CodeMsg.CODE_FAIL.getMsg());
                responseResult.setCode(CodeMsg.CODE_FAIL.getCode());
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }
        return responseResult;
    }

    //9.安全退出
    @RequestMapping("logOut")
    public ResponseResult logOut(){
        //获取认证主体subject 登录认证
        Subject subject = SecurityUtils.getSubject();
        //退出登录
        subject.logout();

        ResponseResult responseResult = new ResponseResult();
        responseResult.setMsg(CodeMsg.LOGIN_OUT.getMsg());
        responseResult.setCode(CodeMsg.LOGIN_OUT.getCode());
        return responseResult;
    }

    //10.根据用户名username，查询所有信息 回显
    @RequestMapping("userAll")
    public ResponseResult UserAll(String username) {
        System.out.println("username = " + username);

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("username", username);
        User user = userService.getOne(userQueryWrapper);

        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(user);
        responseResult.setMsg(CodeMsg.SELECT_SUCCESS.getMsg());
        responseResult.setCode(CodeMsg.SELECT_SUCCESS.getCode());

        return responseResult;
    }

    //11.基本资料的编辑操作,根据username编辑
    @RequestMapping("getByUsername")
    public ResponseResult getByUsername(User user) {

        System.out.println("user = " + user);
        userService.updateById(user);

        ResponseResult responseResult = new ResponseResult();
        responseResult.setMsg(CodeMsg.UPDATE_SUCCESS.getMsg());
        responseResult.setCode(CodeMsg.UPDATE_SUCCESS.getCode());
        return responseResult;
    }

    //12.修改密码
    @RequestMapping("updatePassword")
    public ResponseResult updatePassword(String oldPwd,String newPwd,String username){
        System.out.println("oldPwd XXXXXXXXXX= " + oldPwd);
        System.out.println("newPwd XXXXXXXXXX= " + newPwd);
        System.out.println("username = " + username);

        //创见条件构造器
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("username", username);
        //创建需要修改的数据
        User user = new User();
        String salt = SaltUtil.getSalt(8);
        user.setSalt(salt);
        String md5Pwd = new Md5Hash(newPwd, salt).toHex();
        user.setPassword(md5Pwd);
        //UPDATE user SET password=?, salt=? WHERE (username = ?)
        userService.update(user, userUpdateWrapper);

        ResponseResult responseResult = new ResponseResult();
        responseResult.setMsg(CodeMsg.UPDATE_PASSWORD.getMsg());
        responseResult.setCode(CodeMsg.UPDATE_PASSWORD.getCode());
        return responseResult;
    }


}
